package com.boilermaker.lotterysystem.common.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class JWTUtil {

    /**
     * 密钥：Base64 编码的密钥
     */
    private static final String SECRET = "SDKltwTl3SiWX62dQiSHblEB6O03FG9/vEaivFu6c6g=";

    /**
     * 生成安全密钥：将一个 Base64 编码的密钥解码并创建一个 HMAC SHA 密钥。
     */
    private static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor(Decoders.BASE64.decode(SECRET));

    /**
     * 过期时间（ms）
     */
    private static final long EXPIRATION = 3600000;

    /**
     * 生成 JWT
     *
     * @param claim JWT Payload
     * @return
     */
    public static String genJwt(Map<String, Object> claim) {
        return Jwts.builder()
                .signWith(SECRET_KEY) // Header
                .setClaims(claim) // Payload
                .setIssuedAt(new Date()) // 签发时间
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION)) // 过期时间
                .compact();
    }

    /**
     * 校验 JWT
     *
     * @param jwt
     * @return
     */
    public static Claims parseJWT(String jwt) {

        if (!StringUtils.hasLength(jwt)) {
            log.info("不存在 JWT 令牌");
            return null;
        }

        try {
            return Jwts.parserBuilder()
                    .setSigningKey(SECRET_KEY)
                    .build()
                    .parseClaimsJws(jwt)
                    .getBody();
        } catch (ExpiredJwtException e) {
            log.info("JWT 已过期");
        } catch (Exception e) {
            log.warn("解析 JWT 令牌失败", e);
        }

        return null;
    }

    /**
     * 从 JWT Payload 中获取用户 ID
     *
     * @param jwt
     * @return
     */
    public static Integer getUserIdFromJWT(String jwt) {

        Claims claims = JWTUtil.parseJWT(jwt);

        if (claims != null) {
            return claims.get("userId", Integer.class);
        }
        return null;
    }
}